package com.nchu.react.webflux.component;

import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

import java.util.function.BiFunction;

/**
 * @author fujianjian
 * @project react-learning
 * @date 2018/9/21 下午3:31
 */
@Component
public class CalculatorHandler {

    public Mono<ServerResponse> add(final ServerRequest serverRequest) {
        return calculate(serverRequest, (V1, V2) -> V1 + V2);
    }

    public Mono<ServerResponse> subtract(final ServerRequest request) {
        return calculate(request, (V1, V2) -> V1 - V2);
    }

    public Mono<ServerResponse> multiply(final ServerRequest request) {
        return calculate(request, (V1, V2) -> V1 * V2);
    }

    public Mono<ServerResponse> divide(final ServerRequest request) {
        return calculate(request, (V1, V2) -> V1 / V2);
    }


    private Mono<ServerResponse> calculate(final ServerRequest request,
                                           final BiFunction<Integer, Integer, Integer> calculateFunc) {

        Tuple2<Integer, Integer> operands = extractOperands(request);
        return ServerResponse.ok()
                .body(Mono.just(calculateFunc.apply(operands.getT1(), operands.getT2())), Integer.class);

    }

    private Tuple2<Integer, Integer> extractOperands(ServerRequest request) {
        return Tuples.of(parseOperand(request, "v1"), parseOperand(request, "v2"));
    }

    private Integer parseOperand(final ServerRequest request, String paramName) {
        return Integer.parseInt(request.queryParam(paramName).orElse("0"));
    }
}
